/**
 * 
 */
package org.ejc.struts.registration;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Locale;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Category;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
import org.ejc.api.payment.PaymentAPILocal;
import org.ejc.api.payment.PaymentAPIUtil;
import org.ejc.api.price.PriceTypeAPIUtil;
import org.ejc.api.transaction.TransactionAPIUtil;
import org.ejc.api.registration.RegistrationAPIUtil;
import org.ejc.persist.model.Price;
import org.ejc.persist.model.Registrant;
import org.ejc.persist.model.Transaction;
import org.ejc.session.EJCSession;
import org.ejc.tech.combo.ComboConstants;
import org.ejc.tech.combo.ComboMgr;

/**
 * @struts.action path="/struts/register/paymentAction" scope="request"
 *                parameter="methodToCall" name="paymentForm"
 *                validate="false"
 *                input="/struts/register/payment.jsp"
 * 
 * @struts.action-forward name="prePaymentSuccess" path="/struts/register/payment.jsp"
 * @struts.action-forward name="paymentSuccess" path="/struts/register/registrationComplete.jsp"
 * 
 * @author Brian Boyle
 */
public class PaymentAction extends DispatchAction {

	Category log = Category.getInstance(PaymentAction.class);
	
	/**
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward prePayment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
	throws Exception 
	{
		log.debug("In prePayment of Payment Action!");
		
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		ejcSession.setCurrentAction("Payment");
		
		request.setAttribute("priceTypes",getPriceTypesForRegistration(request.getLocale()));
		
		return mapping.findForward("prePaymentSuccess");
	}
	
	/**
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward selectPriceType(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
	throws Exception 
	{
		log.debug("Selected a Price Type!");
		PaymentForm paymentForm = (PaymentForm)form;
		Integer priceTypeId = paymentForm.getPriceTypeId();
		retrievePrice(request, response, priceTypeId);
		
		return null;
	}
	
	protected void retrievePrice(HttpServletRequest request, HttpServletResponse response, Integer priceTypeId) 
	throws EJBException, NamingException, CreateException, IOException
	{
		Price price = PriceTypeAPIUtil.getLocalHome().create().getPriceByPriceTypeId(priceTypeId);

		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		ejcSession.setCurrentPrice(price);
		
		PrintWriter out = response.getWriter();
		out.print(price.getPriceAmount());
		request.setAttribute("priceTypes",getPriceTypesForRegistration(request.getLocale()));
	}
	
	/**
	 * 
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ActionForward processPayment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
	throws Exception 
	{
		ActionMessages errors = form.validate( mapping, request );
		boolean isConvActive=RegistrationAPIUtil.getLocalHome().create().isConventionActive();
		
		if(!isConvActive){
			if(errors==null)errors=new ActionMessages();
			errors.add("InactiveConv",new ActionMessage("convention.inactive"));
			request.setAttribute("priceTypes",getPriceTypesForRegistration(request.getLocale()));
		}
		
		if ( errors != null && !errors.isEmpty() || isConvActive==false) {
			log.fatal("There are errors");
			saveErrors(request, errors);            
			request.setAttribute("priceTypes",getPriceTypesForRegistration(request.getLocale()));
			return (mapping.findForward("prePaymentSuccess"));
		}
		PaymentForm paymentForm = (PaymentForm) form;
		HttpSession session = request.getSession();
		EJCSession ejcSession = (EJCSession) session.getAttribute("ejcSession");
		boolean isAdmin=ejcSession.getExecutive().isAdmin();
		
		
		Integer conventionId = ejcSession.getConvention().getConventionId();
		Integer registrantId = ejcSession.getConventionRegistrant().getRegistrantId();
		Integer executiveId = ejcSession.getExecutive().getExecutiveId();
		Integer priceId = ejcSession.getCurrentPrice().getPriceId();
		
		Transaction existingTransaction = TransactionAPIUtil.getLocalHome().create()
											.getTransactionByRegistrantId(ejcSession.getConventionRegistrant().getRegistrant());
		
		
		if(existingTransaction != null){
			log.debug("Invalid payment. A payment already exists for reg["+registrantId+"]");
			ActionMessages transErrors = new ActionErrors();
			String firstName = ejcSession.getConventionRegistrant().getRegistrant().getFirstName();
			String lastName = ejcSession.getConventionRegistrant().getRegistrant().getLastName();
			ActionMessage msg = new ActionMessage("errors.payment.inValid", firstName + " " + lastName);
			transErrors.add("message1", msg);
			saveMessages(request, transErrors);
//			Setup the dropdown lists again
			request.setAttribute("priceTypes",getPriceTypesForRegistration(request.getLocale()));
			return mapping.findForward("prePaymentSuccess");
		}
		
		Double transactionAmount=0.0;
		
		if(!isAdmin){
			//not and admin => Tx Amnt is the actual price !
			transactionAmount= PriceTypeAPIUtil.getLocalHome().create().getPriceByPriceId(priceId);
			request.setAttribute("paidAmount",transactionAmount);
		}else if(isAdmin && paymentForm.getPaymentAmount().doubleValue()>0 ){
			//==> U are an admin and u have entered a val in the area and its gt 0
			transactionAmount=paymentForm.getPaymentAmount().doubleValue();
			request.setAttribute("paidAmount", paymentForm.getPaymentAmount().doubleValue());
		}else if(isAdmin && request.getParameter("paymentAmount").length()==0){
			//	u'r an admin and u've entented in nothing in the area
			// default to regular price.
			transactionAmount= PriceTypeAPIUtil.getLocalHome().create().getPriceByPriceId(priceId);
			request.setAttribute("paidAmount",transactionAmount);
		}else if(isAdmin && paymentForm.getPaymentAmount().doubleValue()==0 ){
			//==> U are an admin and u have entered a val in the area and its == 0
			transactionAmount=0.0;
			request.setAttribute("paidAmount", 0.0);
		}
		
		Transaction transaction = PaymentAPIUtil.getLocalHome().create().createPayment
					(conventionId, registrantId, executiveId, priceId,transactionAmount);
		
				
		ejcSession.setTransaction(transaction);
		ejcSession.setCurrentAction("Complete");
		
		//Add a Create Sucessful Message
		ActionMessages messages = new ActionMessages();
		ActionMessage msg = new ActionMessage("info.register.createSuccessful");
		messages.add("message1", msg);
		saveMessages(request, messages);
		return mapping.findForward("paymentSuccess");
	}
	
	
	/**
	 * Retrieve a list of the countries
	 * @param locale The user locale
	 * @return List of countries
	 */
	private Collection getPriceTypesForRegistration(Locale locale){
		return ComboMgr.getInstance().getComboContents(ComboConstants.PRICE_TYPE,locale);
	}
	
}
